#include"hashmap.h"
#include"head.h"
#define INIT_CAPACITY 20
HashMap *createHashMap()
{
	HashMap *map = (HashMap *)malloc(sizeof(HashMap));
    if(map==NULL)
    {
	    return NULL;
    }
    map->_capacity = INIT_CAPACITY;
    map->_size = 0;
    map->_table = (node_t **)malloc(sizeof(node_t *) * INIT_CAPACITY);
    if(!map->_table)
    {
	    free(map);
	    return NULL;
    }
    memset(map->_table,0,sizeof(node_t *)*INIT_CAPACITY);
    return map;
}
void freeHashMap(HashMap *table)
{

    if (!table) {
        return;
    }
    for (int i = 0; i < table->_capacity; i++) {
        node_t *node = table->_table[i];
        while (node) {
            node_t *temp = node;
            node = node->pNext;
            free(temp->_key);
            free(temp->_value);
            free(temp);
        }
    }
    free(table->_table);
    free(table);

}
void insert(HashMap **table, char *key, char *value)
{
	if (!table || !*table || !key || !value) {
		return;
	}
	HashMap *map = *table;
	int index = hash(key, map->_capacity);
	node_t *node = map->_table[index];
	while (node) {
		if (strcmp(node->_key, key) == 0) {
			free(node->_value);
			node->_value = strdup(value);
			return;
		}
		node = node->pNext;
	}
	node_t *newNode = (node_t *)malloc(sizeof(node_t));
	if (!newNode) {
		return;
	}
	newNode->_key = strdup(key);
	newNode->_value = strdup(value);
	newNode->pNext = map->_table[index];
	map->_table[index] = newNode;
	map->_size++;
}
int hash(char *key, int capacity)
{
	unsigned long index = 0;
	for (int i = 0; key[i] != '\0'; i++) {
		index = index * 31 + key[i];
	}
	return index % capacity;
}
void resize(HashMap **table)
{
	if (!table || !*table) {
		return;
	}
	HashMap *map = *table;
	int newCapacity = map->_capacity * 2;
	node_t **newTable = (node_t **)malloc(sizeof(node_t *) * newCapacity);
	if (!newTable) {
		return;
	}
	memset(newTable, 0, sizeof(node_t *) * newCapacity);

	for (int i = 0; i < map->_capacity; i++) {
		node_t *node = map->_table[i];
		while (node) {
			node_t *temp = node;
			node = node->pNext;
			int newIndex = hash(temp->_key, newCapacity);
			temp->pNext = newTable[newIndex];
			newTable[newIndex] = temp;
		}
	}

	free(map->_table);
	map->_table = newTable;
	map->_capacity = newCapacity;
}
char *getKey(HashMap *map, char *key)
{
	if (!map || !key) {
		return NULL;
	}
	int index = hash(key, map->_capacity);
	node_t *node = map->_table[index];
	while (node) {
		if (strcmp(node->_key, key) == 0) {
			return node->_value;
		}
		node = node->pNext;
	}
	return NULL;
}
char *toString(HashMap *map)
{
	if (!map) {
		return NULL;
	}
	int length = 0;
	char *result = (char *)malloc(sizeof(char) * 1024);
	if (!result) {
		return NULL;
	}
	result[0] = '\0';

	for (int i = 0; i < map->_capacity; i++) {
		node_t *node = map->_table[i];
		while (node) {
			int needed = snprintf(NULL, 0, "%s=%s, ", node->_key,
					      node->_value);
			if (length + needed >= 1024) {
				char *new_result = (char *)realloc(
					result, length + needed + 1);
				if (!new_result) {
					free(result);
					return NULL;
				}
				result = new_result;
			}
			sprintf(result + length, "%s=%s, ", node->_key,
				node->_value);
			length += needed - 2; // 更新长度，减去多余的", "
			node = node->pNext;
		}
	}
	if (length > 0) {
		result[length - 2] = '\0'; // 移除最后一个逗号和空格
	}
	return result;
}

// 获取配置文件中的参数
char *getParameter(const char *key)
{
	FILE *file = fopen("config.ini", "r");
	if (!file) {
		perror("OPEN CONFIG ERROR");
		return NULL;
	}

	char line[100];
	while (fgets(line, sizeof(line), file)) {
		// 去掉换行符
		line[strcspn(line, "\n")] = '\0';

		char *line_key = strtok(line, "=");
		if (line_key && strcmp(key, line_key) == 0) {
			char *line_value = strtok(NULL, "=");
			if (line_value) {
				char *value = strdup(line_value);
				fclose(file);
				return value;
			}
		}
	}

	fclose(file);
	return NULL;
}

// 创建参数映射
HashMap *parameterMap()
{
	HashMap *map = createHashMap();

	// 获取配置文件中的参数
	char *ip = getParameter("ip");
	char *port = getParameter("port");
	char *threadNum = getParameter("threadNum");

	// 插入到哈希表
	if (ip)
		insert(&map, "ip", ip);
	if (port)
		insert(&map, "port", port);
	if (threadNum)
		insert(&map, "threadNum", threadNum);

	// 释放内存
	free(ip);
	free(port);
	free(threadNum);

	return map;
}

// test
// int main()
// {
//     HashMap * map = parameterMap();
//     printf("ip:%s\n", get(map, "ip"));
//     printf("port:%s\n",get(map,"port"));

//     return 0;
// }
